-------Alphabetizing: Blue Level-------
A 4am crack                  2017-04-28
---------------------------------------

Name: Alphabetizing: Blue Level
Genre: educational
Year: 1983
Publisher: Methods & Solutions
Platform: Apple ][+ or later
Media: 1 single-sided 5.25-inch disk
OS: DOS 3.3
Previous cracks: none

This disk was automatically cracked by
Passport. Here is the transcript:

                 --v--

READING FROM S6,D1
T00,S00 FOUND DOS 3.3 BOOTLOADER
USING DISK'S OWN RWTS
WRITING TO S5,D2
T00,S06,$7A: AA -> D5
T00,S06,$7F: D5 -> AA
CRACK COMPLETE.

                 --^--

[Narrator]
But the crack was not complete.

                   ~

The copy that Passport produces is in a
standard format, fully readable by
third-party tools. But when I boot it,
the disk can not read itself; it just
grinds and crashes. Which is odd.

Passport used the original disk's own
RWTS to read it (successfully). It even
patched the RWTS afterwards to
accomodate the newly standardized
format. If the copy can't read itself
after all that, it means there must be
additional code somewhere that is
modifying the RWTS in a way that
Passport doesn't detect.

Yet.

                   ~

               Chapter 0
    In Which We Complete The Crack


Turning to my trusty Disk Fixer sector
editor, I start my investigation as any
investigation should start: on track 0,
sector 0. It is identical to an
unprotected DOS 3.3 system master disk.
It even loads DOS in low memory ($1D00+
instead of $9D00+).

On to sector 1, then.

                 --v--

T00,S01
----------- DISASSEMBLY MODE ----------
; normal (setting up RWTS parameter
; table for the DOS read)
0000:8E E9 37       STX   $37E9
0003:8E F7 37       STX   $37F7
0006:A9 01          LDA   #$01
0008:8D F8 37       STA   $37F8
000B:8D EA 37       STA   $37EA
000E:AD E0 37       LDA   $37E0
0011:8D E1 37       STA   $37E1

; normal, start reading DOS at T02,S04
0014:A9 02          LDA   #$02
0016:8D EC 37       STA   $37EC
0019:A9 04          LDA   #$04
001B:8D ED 37       STA   $37ED
001E:AC E7 37       LDY   $37E7
0021:88             DEY
0022:8C F1 37       STY   $37F1
0025:A9 01          LDA   #$01
0027:8D F4 37       STA   $37F4
002A:8A             TXA
002B:4A             LSR
002C:4A             LSR
002D:4A             LSR
002E:4A             LSR
002F:AA             TAX
0030:A9 00          LDA   #$00
0032:9D F8 04       STA   $04F8,X
0035:9D 78 04       STA   $0478,X

; normal, do the actual read
0038:20 93 37       JSR   $3793
003B:A2 FF          LDX   #$FF
003D:9A             TXS
003E:8E EB 37       STX   $37EB

; slightly unusual but it's nothing
; illegitimate (just machine
; initialization stuff, not shown)
0041:20 69 3A       JSR   $3A69
0044:20 89 FE       JSR   $FE89

; this, on the other hand, is quite
; suspicious
0047:4C CE 36       JMP   $36CE

                 --^--

After reading DOS from tracks 0-2, a
standard disk that loaded in low memory
would call $1B03 to relocate DOS to
higher memory (from $1D00 to $9D00 on a
machine with at least 48K of memory).
But this disk seems to have something
extra at $36CE. I don't like extra.

Since sector 0 was bog standard, I know
that $3600 is loaded from sector 0. The
drive firmware loads sector 0 at $0800,
then the code there loads it again at
$3600 when it reads the rest of the
RWTS from sectors 1-9.

Back to sector 0.

                 --v--

T00,S00
----------- DISASSEMBLY MODE ----------
00CE:A9 AA          LDA   #$AA
00D0:8D 55 39       STA   $3955
00D3:A9 D5          LDA   #$D5
00D5:8D 5F 39       STA   $395F
00D8:A2 02          LDX   #$02
00DA:BD E6 36       LDA   $36E6,X
00DD:9D 5A 3E       STA   $3E5A,X
00E0:CA             DEX
00E1:10 F7          BPL   $00DA
00E3:4C 03 1B       JMP   $1B03

Aha! It's modifying the RWTS in memory
to look for a different address
prologue -- $AA $D5 $96 instead of the
standard $D5 $AA $96.

But wait, what's this loop to copy, er,
three whole bytes into $3E5A?

                 --v--

T00,S00
----------- DISASSEMBLY MODE ----------
00E6:48             PHA
00E7:A0 01          LDY   #$01

                 --^--

Well if that's here, what's there?
The page at $3E00 is read from track 0,
sector 8.

                 --v--

T00,S08
----------- DISASSEMBLY MODE ----------
005A:4C B4 36       JMP   $36B4

                 --^--

More "extra" code --overwritten after
DOS loads, but still, it exists during
boot and might explain why my copy
can't read itself during boot.

Back to sector 0.

                 --v--

T00,S00
----------- DISASSEMBLY MODE ----------
; I believe the accumulator has the
; current track on entry (possibly the
; phase (track*2), but either way, we
; are just testing for 0 so they end up
; the same)
00B4:48             PHA
00B5:68             PLA
00B6:48             PHA

; different treatment for track 0
00B7:F0 06          BEQ   $00BF

; fall through to here if track > 0
00B9:A9 AA          LDA   #$AA
00BB:A0 D5          LDY   #$D5
00BD:D0 04          BNE   $00C3

; execution continues here (from $36B7)
; for track 0
00BF:A9 D5          LDA   #$D5
00C1:A0 AA          LDY   #$AA

; Execution continues here regardless
; of the track (either by falling
; through or via the branch at $36BD).
; We're modifying the RWTS, either
; setting a normal address prologue
; (for track 0) or the reversed one
; ($AA $D5 $96) that we saw earlier
00C3:8D 55 39       STA   $3955
00C6:8C 5F 39       STY   $395F

; continue with legitimate RWTS code
00C9:A0 01          LDY   #$01
00CB:4C 5D 3E       JMP   $3E5D

                 --^--

OK, there are two things going on here.
As it exists on disk, the RWTS will
change the address prologue based on
the track we're reading -- $D5 $AA $96
for track 0, $AA $D5 $96 for all other
tracks. This is accomplished by the JMP
to $36B4 (from $3E5A). This code is
called repeatedly during early boot,
while it's loading DOS.

After DOS is in low memory ($1D00+) but
before it gets relocated to $9D00+, we
call the routine at $36CE (from $3747).
This is a once-and-done thing. It
permanently alters the RWTS to hardcode
the reverse prologue ($AA $D5 $96) used
on all tracks other than track 0. It
also removes the JMP at $3E5A and
replaces it with the code that normally
lives there on an unprotected disk.

The net effect is that, after DOS
loads, the RWTS can no longer read
track 0. This turns out not to matter
because the disk never tries to read
track 0 after boot.

Why all this fuss? Because the disk
loads DOS in low memory first, the
RWTS swapper (at $36B4) needs to live
in low memory. But the routine to
relocate DOS to higher memory wouldn't
fix the JMP at $3E5A nor the JMP inside
the custom RWTS swapper at $36CB. So I
guess they decided it was simpler to
remove the RWTS swapper altogether
after DOS loads.

At any rate, I can make two small
changes to get my non-working copy to
boot:

; don't change RWTS prologues after
; loading DOS (jump to $36D8 instead of
; $36CE)
T00,S01,$48: CE -> D8

; neutralize the RWTS swapper (make it
; fall through so it always uses the
; standard values)
T00,S00,$BD: D0 -> 24

]PR#6
...works, and it is glorious...

                   ~

               Chapter 1
    In Which We Complete The Cycle


I have two other disks from the same
publisher which contain an identical
RWTS swapper, so I've added support for
this disk to Passport. The next version
of Passport will fully crack this disk
and others like it:

                 --v--

READING FROM S6,D1
T00,S00 FOUND DOS 3.3 BOOTLOADER
USING DISK'S OWN RWTS
WRITING TO S5,D2
T00,S06,$7A: AA -> D5
T00,S06,$7F: D5 -> AA
T00,S00 RWTS CHANGES BASED ON TRACK
T00,S00,$BD: D0 -> 24
T00,S01,$48: CE -> D8
CRACK COMPLETE.

                 --^--

Quod erat liberandum.

---------------------------------------
A 4am crack                    No. 1174
------------------EOF------------------
